package com.study.example.gameserver.module.player.entity;

import com.sparrow.actor.AbstractActor;
import com.sparrow.common.aoi.domain.AOIEntity;
import com.sparrow.common.aoi.domain.EntityType;
import com.sparrow.common.attr.AttrBox;
import com.sparrow.common.cd.CDBox;
import com.sparrow.common.mergeupdate.MergeUpdateBox;
import com.sparrow.common.schedule.playerscheduler.PlayerScheduler;
import com.sparrow.socket.tcp.session.impl.GameSession;
import com.sparrow.common.buff.BuffBox;
import com.sparrow.common.buff.domain.IBuffActor;
import com.sparrow.common.map.Position;
import com.study.example.gameserver.base.def.CDType;
import com.study.example.gameserver.base.util.TipHelper;
import com.study.example.gameserver.module.attr.domain.AttrType;
import com.study.example.gameserver.module.entity.PlayerData;
import com.study.example.gameserver.module.scene.domain.MapState;
import com.study.example.gameserver.module.scene.entity.IPlayerEntity;
import com.study.example.gameserver.module.player.domain.PlayerDataType;

import java.util.concurrent.Executor;

public class Player extends AbstractActor implements IBuffActor, AOIEntity, IPlayerEntity {

    private Long playerId;
    private GameSession session;
    private PlayerEntity entity;
    private PlayerData[] playerData;
    private volatile boolean initialize;
    /**
     * CD控制器
     */
    private CDBox<CDType> cdBox;
    /**
     * 属性盒子
     */
    private AttrBox attrBox;
    /**
     * 合并更新器
     */
    private MergeUpdateBox mergeUpdateBox;
    /**
     * Buff容器
     */
    private BuffBox buffBox;

    private PlayerScheduler scheduler;

    private int aoiX;
    private int aoiY;

    private MapState mapState;

    public Player(long playerId, Executor executor) {
        super(executor);
        this.playerId = playerId;
        this.cdBox = new CDBox<>();
        this.mapState = MapState.NORMAL;
    }


    public void setMapState(MapState mapState) {
        this.mapState = mapState;
    }

    public MapState getMapState() {
        return mapState;
    }

    public void setAttrBox(AttrBox attrBox) {
        this.attrBox = attrBox;
    }

    public AttrBox getAttrBox() {
        return attrBox;
    }

    public void setSession(GameSession session) {
        this.session = session;
    }

    public GameSession getSession() {
        return session;
    }

    public void sendPacket(Object packet) {
        session.write(packet);
    }

    public void setEntity(PlayerEntity entity) {
        this.entity = entity;
    }

    public PlayerEntity getEntity() {
        return entity;
    }

    public void setInitialize(boolean initialize) {
        this.initialize = initialize;
    }

    public boolean isInitialize() {
        return initialize;
    }

    public long getPlayerId() {
        return playerId;
    }


    public String getPlayerName() {
        return entity.getName();
    }

    public void setPlayerData(PlayerData[] playerData) {
        this.playerData = playerData;
    }

    public <T> T getData(PlayerDataType playerDataType) {
        return (T) playerData[playerDataType.getOrder() - 1];
    }

    public CDBox<CDType> getCdBox() {
        return cdBox;
    }

    public int getLevel() {
        return entity.getLevel();
    }

    public void setMergeUpdateBox(MergeUpdateBox mergeUpdateBox) {
        this.mergeUpdateBox = mergeUpdateBox;
    }

    public MergeUpdateBox getMergeUpdateBox() {
        return mergeUpdateBox;
    }

    public int getServer() {
        return entity.getServer();
    }

    public void setBuffBox(BuffBox buffBox) {
        this.buffBox = buffBox;
    }

    public BuffBox getBuffBox() {
        return buffBox;
    }

    @Override
    public long getAOIId() {
        return playerId;
    }


    @Override
    public int getAOIX() {
        return aoiX;
    }

    @Override
    public void setAOIX(int x) {
        this.aoiX = x;
    }

    @Override
    public void setAOIY(int y) {
        this.aoiY = y;
    }

    @Override
    public int getAOIY() {
        return aoiY;
    }

    @Override
    public EntityType getEntityType() {
        return EntityType.PLAYER;
    }


    public void setScheduler(PlayerScheduler scheduler) {
        this.scheduler = scheduler;
    }

    public PlayerScheduler getScheduler() {
        return scheduler;
    }

    @Override
    public long getId() {
        return playerId;
    }

    public Position getPos() {
        return entity.getPos();
    }

    @Override
    public void setPos(Position pos) {
        entity.setPos(pos);
    }

    @Override
    public int getMapId() {
        return entity.getMapId();
    }

    @Override
    public void setMapId(int mapId) {
        entity.setMapId(mapId);
    }

    public int getSceneId() {
        return entity.getSceneId();
    }

    @Override
    public void setSceneId(int sceneId) {
        entity.setSceneId(sceneId);
    }

    public int getLineId() {
        return entity.getLineId();
    }

    @Override
    public void setLineId(int lineId) {
        entity.setLineId(lineId);
    }

    public int getAngle() {
        return entity.getAngle();
    }

    @Override
    public void setAngle(int angle) {
        entity.setAngle(angle);
    }

    public void sendTip(String content) {
        TipHelper.sendTip(session, content);
    }

    @Override
    public int getHp() {
        return entity.getHp();
    }

    @Override
    public void setHp(int hp) {
        entity.setHp(hp);
    }

    @Override
    public int getMaxHp() {
        return entity.getMaxHp();
    }

    public void setMaxHp(int hp) {
        this.entity.setMaxHp(hp);
    }

    @Override
    public boolean isAlive() {
        return getHp() > 0;
    }

    @Override
    public void setAtk(int atk) {

    }

    @Override
    public int takeDamage(int dmg) {
        int currentHp = getHp();
        int newHp = currentHp - dmg;
        if (newHp < 0) {
            newHp = 0;
        }
        setHp(newHp);
        // 返回真实扣除的血量
        return currentHp - newHp;
    }

    @Override
    public int getAtk() {
        return (int) attrBox.getTotalAttr().get(AttrType.Atk);
    }

    @Override
    public float getSpeed() {
        return 5;
    }

    @Override
    public void setSpeed(float speed) {

    }

    public long getFight() {
        return entity.getFightForce();
    }

    public int getExp() {
        return entity.getExp();
    }

    public void save() {
        entity.update();
    }
}

